﻿#pragma once
#include "spdlog/spdlog.h"
#include "spdlog/sinks/stdout_color_sinks.h"
#include "spdlog/sinks/basic_file_sink.h"
#include "spdlog/sinks/stdout_sinks.h"
#include "spdlog/sinks/rotating_file_sink.h"

#include "spdlog/fmt/fmt.h"

// #define FMT_HEADER_ONLY
// #include "spdlog/fmt/bundled/format.h"

#include <stdarg.h>

template <typename T>
class Singleton
{
public:
    static T * instance()
    {
        if (m_instance == NULL)
            m_instance = new T();
        return m_instance;
    }

private:
    Singleton() {}
    Singleton(const Singleton<T> &);
    Singleton<T> & operator = (const Singleton<T> &);
    ~Singleton() {}

private:
    static T * m_instance;
};

template <typename T>
T * Singleton<T>::m_instance = NULL;

class Logging
{
private:
    std::shared_ptr<spdlog::logger> m_console;
    std::shared_ptr<spdlog::logger> m_console_file;

    bool m_isConsoleFile;

public:
    Logging();
    ~Logging();

    template<typename... Args>
    inline void info(spdlog::string_view_t fmt, const Args &... args)
    {
        m_console->info(fmt, args...);
        if (m_isConsoleFile == true)
            m_console_file->info(fmt, args...);
    }

    template<typename... Args>
    inline void warn(spdlog::string_view_t fmt, const Args &... args)
    {
        m_console->warn(fmt, args...);
        if (m_isConsoleFile == true)
            m_console_file->warn(fmt, args...);
        
    }

    template<typename... Args>
    inline void critical(spdlog::string_view_t fmt, const Args &... args)
    {
        m_console->critical(fmt, args...);
        if (m_isConsoleFile == true)
            m_console_file->critical(fmt, args...);
    }

    template<typename... Args>
    inline void error(spdlog::string_view_t fmt, const Args &... args)
    {
        m_console->error(fmt, args...);
        if (m_isConsoleFile == true)
            m_console_file->error(fmt, args...);
    }

    void setLogPath(const char* path, int size, int num);
};

typedef Singleton<Logging> Logger;